using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;

namespace Skywave.Windows.Forms
{
    public class SheetRange
    {
        private string BuildKey(int i, int j)
        {
            return i + ", " + j;
        }
        private int mRow1, mColumn1, mRow2, mColumn2;
        private Hashtable mDCells;

        public SheetRange(int row1, int column1, int row2, int column2, Hashtable inDCells)
        {
            mRow1 = row1; mRow2 = row2;
            mColumn1 = column1; mColumn2 = column2;
            mDCells = inDCells;
        }

        public int Row1
        {
            get
            {
                return mRow1;
            }
        }
        public int Row2
        {
            get
            {
                return mRow2;
            }
        }
        public int Column1
        {
            get
            {
                return mColumn1;
            }
        }
        public int Column2
        {
            get
            {
                return mColumn2;
            }
        }

        public Color BorderColor
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                Color firstBColor;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return Color.Empty;
                xCell = (SheetCell)mDCells[key];
                firstBColor = xCell.BorderColor;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return Color.Empty;
                        xCell = (SheetCell)mDCells[key];
                        if (!firstBColor.Equals(xCell.BorderColor)) return Color.Empty;
                    }
                }
                return firstBColor;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.BorderColor = value;
                    }
                }
            }
        }

        public Color BackColor
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                Color firstBColor;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return Color.Empty;
                xCell = (SheetCell)mDCells[key];
                firstBColor = xCell.BackColor;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return Color.Empty;
                        xCell = (SheetCell)mDCells[key];
                        if (!firstBColor.Equals(xCell.BackColor)) return Color.Empty;
                    }
                }
                return firstBColor;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.BackColor = value;
                    }
                }
            }
        }

        public Color ForeColor
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                Color first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return Color.Empty;
                xCell = (SheetCell)mDCells[key];
                first = xCell.ForeColor;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return Color.Empty;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.ForeColor)) return Color.Empty;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.ForeColor = value;
                    }
                }
            }
        }

        public ContentAlignment TextAlign
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                ContentAlignment first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return ContentAlignment.MiddleLeft;
                xCell = (SheetCell)mDCells[key];
                first = xCell.TextAlign;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return ContentAlignment.MiddleLeft;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.TextAlign)) return ContentAlignment.MiddleLeft;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.TextAlign = value;
                    }
                }
            }
        }

        public SheetOwnerDrawModes OwnerDraw
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                SheetOwnerDrawModes first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return SheetOwnerDrawModes.None;
                xCell = (SheetCell)mDCells[key];
                first = xCell.OwnerDraw;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return SheetOwnerDrawModes.None;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.OwnerDraw)) return SheetOwnerDrawModes.None;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.OwnerDraw = value;
                    }
                }
            }
        }

        public bool RightToLeft
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                bool first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return false;
                xCell = (SheetCell)mDCells[key];
                first = xCell.RightToLeft;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return false;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.RightToLeft)) return false;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.RightToLeft = value;
                    }
                }
            }
        }

        public bool ShrinkToFit
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                bool first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return false;
                xCell = (SheetCell)mDCells[key];
                first = xCell.ShrinkToFit;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return false;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.ShrinkToFit)) return false;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.ShrinkToFit = value;
                    }
                }
            }
        }

        public bool Warp
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                bool first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return false;
                xCell = (SheetCell)mDCells[key];
                first = xCell.Warp;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return false;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.Warp)) return false;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.Warp = value;
                    }
                }
            }
        }

        public bool VerticalText
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                bool first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return false;
                xCell = (SheetCell)mDCells[key];
                first = xCell.VerticalText;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return false;
                        xCell = (SheetCell)mDCells[key];
                        if (!first.Equals(xCell.VerticalText)) return false;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.VerticalText = value;
                    }
                }
            }
        }

        public Font Font
        {
            get
            {
                string key;
                SheetCell xCell;
                int r, c;
                Font first;
                key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return null;
                xCell = (SheetCell)mDCells[key];
                first = xCell.Font;
                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) return null;
                        xCell = (SheetCell)mDCells[key];
                        if (first == null || xCell.Font == null || !first.Equals(xCell.Font)) return null;
                    }
                }
                return first;
            }
            set
            {
                string key;
                SheetCell xCell;
                int r, c;

                for (r = mRow1; r <= mRow2; r++)
                {
                    for (c = mColumn1; c <= mColumn2; c++)
                    {
                        key = r + ", " + c;
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        xCell = (SheetCell)mDCells[key];
                        xCell.Font = value;
                    }
                }
            }
        }

        public int GetBorder(SheetRangeBorderTypes type)
        {
            int i, j, b1, b2, b3, b4;
            SheetCell xCell;
            string key;
            int firstBorder = 0;

            if ((type == SheetRangeBorderTypes.MiddleHorizontal) && (mColumn2 == mColumn1)) return 0;
            if ((type == SheetRangeBorderTypes.MiddleVertical) && (mRow2 == mRow1)) return 0;

            switch (type)
            {
                case SheetRangeBorderTypes.MiddleHorizontal:
                    key = BuildKey(mRow1, mColumn1);
                    xCell = (SheetCell)mDCells[key];
                    if (xCell == null) return 0;
                    firstBorder = xCell.GetBorder(SheetBorderTypes.Bottom);
                    for (j = mColumn1; j <= mColumn2; j++)
                    {
                        for (i = mRow1; i < mRow2; i++)
                        {
                            key = BuildKey(i, j);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null) return 0;
                            if (xCell.GetBorder(SheetBorderTypes.Bottom) != firstBorder) return 0;
                        }
                        for (i = mRow1 + 1; i <= mRow2; i++)
                        {
                            key = BuildKey(i, j);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null) return 0;
                            if (xCell.GetBorder(SheetBorderTypes.Top) != firstBorder) return 0;
                        }
                    }
                    return firstBorder;
                case SheetRangeBorderTypes.MiddleVertical:
                    key = BuildKey(mRow1, mColumn1);
                    xCell = (SheetCell)mDCells[key];
                    if (xCell == null) return 0;
                    firstBorder = xCell.GetBorder(SheetBorderTypes.Right);
                    for (i = mRow1; i <= mRow2; i++)
                    {
                        for (j = mColumn1; j < mColumn2; j++)
                        {
                            key = BuildKey(i, j);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null) return 0;
                            if (xCell.GetBorder(SheetBorderTypes.Right) != firstBorder) return 0;
                        }
                        for (i = mRow1 + 1; i <= mRow2; i++)
                        {
                            key = BuildKey(i, j);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null) return 0;
                            if (xCell.GetBorder(SheetBorderTypes.Left) != firstBorder) return 0;
                        }
                    }
                    return firstBorder;
                case SheetRangeBorderTypes.Bottom:
                    key = BuildKey(mRow2, mColumn1);
                    xCell = (SheetCell)mDCells[key];
                    if (xCell == null) return 0;
                    firstBorder = xCell.GetBorder(SheetBorderTypes.Bottom);
                    for (j = mColumn1; j <= mColumn2; j++)
                    {
                        key = BuildKey(mRow2, j);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null) return 0;
                        if (xCell.GetBorder(SheetBorderTypes.Bottom) != firstBorder) return 0;
                    }
                    return firstBorder;
                case SheetRangeBorderTypes.Left:
                    key = BuildKey(mRow1, mColumn1);
                    xCell = (SheetCell)mDCells[key];
                    if (xCell == null) return 0;
                    firstBorder = xCell.GetBorder(SheetBorderTypes.Left);
                    for (i = mRow1; i <= mRow2; i++)
                    {
                        key = BuildKey(i, mColumn1);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null) return 0;
                        if (xCell.GetBorder(SheetBorderTypes.Left) != firstBorder) return 0;
                    }
                    return firstBorder;
                case SheetRangeBorderTypes.Right:
                    key = BuildKey(mRow1, mColumn2);
                    xCell = (SheetCell)mDCells[key];
                    if (xCell == null) return 0;
                    firstBorder = xCell.GetBorder(SheetBorderTypes.Right);
                    for (i = mRow1; i <= mRow2; i++)
                    {
                        key = BuildKey(i, mColumn2);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null) return 0;
                        if (xCell.GetBorder(SheetBorderTypes.Right) != firstBorder) return 0;
                    }
                    return firstBorder;
                case SheetRangeBorderTypes.Top:
                    key = BuildKey(mRow1, mColumn1);
                    xCell = (SheetCell)mDCells[key];
                    if (xCell == null) return 0;
                    firstBorder = xCell.GetBorder(SheetBorderTypes.Top);
                    for (j = mColumn1; j <= mColumn2; j++)
                    {
                        key = BuildKey(mRow1, j);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null) return 0;
                        if (xCell.GetBorder(SheetBorderTypes.Top) != firstBorder) return 0;
                    }
                    return firstBorder;
                case SheetRangeBorderTypes.Inner:
                    i = GetBorder(SheetRangeBorderTypes.MiddleHorizontal);
                    j = GetBorder(SheetRangeBorderTypes.MiddleVertical);
                    if (i == j) return i; else return 0;
                case SheetRangeBorderTypes.Outer:
                    b1 = GetBorder(SheetRangeBorderTypes.Left);
                    b2 = GetBorder(SheetRangeBorderTypes.Right);
                    b3 = GetBorder(SheetRangeBorderTypes.Top);
                    b4 = GetBorder(SheetRangeBorderTypes.Bottom);
                    if ((b1 == b2) && (b2 == b3) && (b3 == b4)) return b1; else return 0;
                case SheetRangeBorderTypes.InnerOuter:
                    b1 = GetBorder(SheetRangeBorderTypes.Inner);
                    b2 = GetBorder(SheetRangeBorderTypes.Outer);
                    if (b1 == b2) return b1; else return 0;
                default:
                    return 0;
            }
        }
        public void SetBorder(SheetRangeBorderTypes type, int value)
        {
            int i, j;
            SheetCell xCell;
            string key;

            if (Merged)
            {
                switch (type)
                {
                    case SheetRangeBorderTypes.Left:
                        key = BuildKey(mRow1, mColumn1);
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Left, value);
                        break;
                    case SheetRangeBorderTypes.Right:
                        key = BuildKey(mRow2, mColumn2);
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Right, value);
                        break;
                    case SheetRangeBorderTypes.Top:
                        key = BuildKey(mRow1, mColumn1);
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Top, value);
                        break;
                    case SheetRangeBorderTypes.Bottom:
                        key = BuildKey(mRow2, mColumn2);
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Bottom, value);
                        break;
                    case SheetRangeBorderTypes.MiddleHorizontal:
                        break;
                    case SheetRangeBorderTypes.MiddleVertical:
                        break;
                    case SheetRangeBorderTypes.Inner:
                        break;
                    case SheetRangeBorderTypes.Outer:
                        key = BuildKey(mRow1, mColumn1);
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Left, value);
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Top, value);
                        key = BuildKey(mRow2, mColumn2);
                        if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Right, value);
                        ((SheetCell)mDCells[key]).SetBorder(SheetBorderTypes.Bottom, value);
                        break;
                    case SheetRangeBorderTypes.InnerOuter:
                        break;
                    default:
                        break;
                }
            }
            else
            {
                switch (type)
                {
                    case SheetRangeBorderTypes.MiddleHorizontal:
                        for (j = mColumn1; j <= mColumn2; j++)
                        {
                            for (i = mRow1; i < mRow2; i++)
                            {
                                key = BuildKey(i, j);
                                if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                                xCell.SetBorder(SheetBorderTypes.Bottom, value);
                            }
                            for (i = mRow1 + 1; i <= mRow2; i++)
                            {
                                key = BuildKey(i, j);
                                if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                                xCell.SetBorder(SheetBorderTypes.Top, value);
                            }
                        }
                        break;
                    case SheetRangeBorderTypes.MiddleVertical:
                        for (i = mRow1; i <= mRow2; i++)
                        {
                            for (j = mColumn1; j < mColumn2; j++)
                            {
                                key = BuildKey(i, j);
                                if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                                xCell.SetBorder(SheetBorderTypes.Right, value);
                            }
                            for (j = mColumn1 + 1; j <= mColumn2; j++)
                            {
                                key = BuildKey(i, j);
                                if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                                xCell.SetBorder(SheetBorderTypes.Left, value);
                            }
                        }
                        break;
                    case SheetRangeBorderTypes.Left:
                        for (i = mRow1; i <= mRow2; i++)
                        {
                            key = BuildKey(i, mColumn1);
                            if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                            xCell.SetBorder(SheetBorderTypes.Left, value);
                        }
                        break;
                    case SheetRangeBorderTypes.Right:
                        for (i = mRow1; i <= mRow2; i++)
                        {
                            key = BuildKey(i, mColumn2);
                            if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                            xCell.SetBorder(SheetBorderTypes.Right, value);
                        }
                        break;
                    case SheetRangeBorderTypes.Top:
                        for (j = mColumn1; j <= mColumn2; j++)
                        {
                            key = BuildKey(mRow1, j);
                            if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                            xCell.SetBorder(SheetBorderTypes.Top, value);
                        }
                        break;
                    case SheetRangeBorderTypes.Bottom:
                        for (j = mColumn1; j <= mColumn2; j++)
                        {
                            key = BuildKey(mRow2, j);
                            if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                            xCell.SetBorder(SheetBorderTypes.Bottom, value);
                        }
                        break;
                    case SheetRangeBorderTypes.Inner:
                        SetBorder(SheetRangeBorderTypes.MiddleHorizontal, value);
                        SetBorder(SheetRangeBorderTypes.MiddleVertical, value);
                        break;
                    case SheetRangeBorderTypes.Outer:
                        SetBorder(SheetRangeBorderTypes.Left, value);
                        SetBorder(SheetRangeBorderTypes.Right, value);
                        SetBorder(SheetRangeBorderTypes.Top, value);
                        SetBorder(SheetRangeBorderTypes.Bottom, value);
                        break;
                    case SheetRangeBorderTypes.InnerOuter:
                        SetBorder(SheetRangeBorderTypes.Inner, value);
                        SetBorder(SheetRangeBorderTypes.Outer, value);
                        break;
                    default:
                        break;
                }
            }
        }

        public object Text
        {
            get
            {
                string key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) return new object(); else return ((SheetCell)mDCells[key]).Text;
            }
            set
            {
                string key = mRow1 + ", " + mColumn1;
                if (!mDCells.ContainsKey(key)) mDCells.Add(key, new SheetCell());
                ((SheetCell)mDCells[key]).Text = value;
            }
        }

        public bool Merged
        {
            get
            {
                int i, j;
                SheetCell xCell;

                if ((mColumn2 == mColumn1) && (mRow2 == mRow1)) return false;
                if ((mColumn2 == mColumn1) && (mRow2 > mRow1))
                {
                    for (i = mRow1 + 1; i < mRow2; i++)
                    {
                        xCell = (SheetCell)(mDCells[BuildKey(i, mColumn1)]);
                        if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Bottom | SheetMergeTypes.Top))) return false;
                    }
                    xCell = (SheetCell)mDCells[BuildKey(mRow1, mColumn1)];
                    if ((xCell == null) || (xCell.Merge != SheetMergeTypes.Bottom)) return false;
                    xCell = (SheetCell)mDCells[BuildKey(mRow2, mColumn1)];
                    if ((xCell == null) || (xCell.Merge != SheetMergeTypes.Top)) return false;
                }
                if ((mColumn2 > mColumn1) && (mRow2 == mRow1))
                {
                    for (i = mColumn1 + 1; i < mColumn2; i++)
                    {
                        xCell = (SheetCell)(mDCells[BuildKey(mRow1, i)]);
                        if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Left | SheetMergeTypes.Right))) return false;
                    }
                    xCell = (SheetCell)mDCells[BuildKey(mRow1, mColumn1)];
                    if ((xCell == null) || (xCell.Merge != SheetMergeTypes.Right)) return false;
                    xCell = (SheetCell)mDCells[BuildKey(mRow1, mColumn2)];
                    if ((xCell == null) || (xCell.Merge != SheetMergeTypes.Left)) return false;
                }
                if ((mRow2 > mRow1) && (mColumn2 > mColumn1))
                {
                    for (i = mRow1 + 1; i < mRow2; i++)
                    {
                        for (j = mColumn1 + 1; j < mColumn2; j++)
                        {
                            xCell = (SheetCell)(mDCells[BuildKey(i, j)]);
                            if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Top | SheetMergeTypes.Bottom | SheetMergeTypes.Left | SheetMergeTypes.Right))) return false;
                        }
                    }
                    for (i = mColumn1 + 1; i < mColumn2; i++)
                    {
                        xCell = (SheetCell)(mDCells[BuildKey(mRow1, i)]);
                        if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Bottom | SheetMergeTypes.Left | SheetMergeTypes.Right))) return false;
                        xCell = (SheetCell)(mDCells[BuildKey(mRow2, i)]);
                        if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Top | SheetMergeTypes.Left | SheetMergeTypes.Right))) return false;
                    }
                    for (i = mRow1 + 1; i < mRow2; i++)
                    {
                        xCell = (SheetCell)(mDCells[BuildKey(i, mColumn1)]);
                        if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Bottom | SheetMergeTypes.Top | SheetMergeTypes.Right))) return false;
                        xCell = (SheetCell)(mDCells[BuildKey(i, mColumn2)]);
                        if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Bottom | SheetMergeTypes.Top | SheetMergeTypes.Left))) return false;
                    }
                    xCell = (SheetCell)mDCells[BuildKey(mRow1, mColumn1)];
                    if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Right | SheetMergeTypes.Bottom))) return false;
                    xCell = (SheetCell)mDCells[BuildKey(mRow1, mColumn2)];
                    if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Left | SheetMergeTypes.Bottom))) return false;
                    xCell = (SheetCell)mDCells[BuildKey(mRow2, mColumn1)];
                    if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Right | SheetMergeTypes.Top))) return false;
                    xCell = (SheetCell)mDCells[BuildKey(mRow2, mColumn2)];
                    if ((xCell == null) || (xCell.Merge != (SheetMergeTypes.Left | SheetMergeTypes.Top))) return false;
                }
                return true;
            }
            set
            {
                int i, j;
                SheetCell xCell;
                string key;
                //if ((mColumn2 == mColumn1) && (mRow2 == mRow1)) return false;
                if (value)
                {
                    if ((mColumn2 == mColumn1) && (mRow2 > mRow1))
                    {
                        for (i = mRow1 + 1; i < mRow2; i++)
                        {
                            key = BuildKey(i, mColumn1);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null)
                            {
                                mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                            }
                            xCell.Merge = SheetMergeTypes.Bottom | SheetMergeTypes.Top;
                        }
                        key = BuildKey(mRow1, mColumn1);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Bottom;
                        key = BuildKey(mRow2, mColumn1);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Top;
                    }
                    if ((mColumn2 > mColumn1) && (mRow2 == mRow1))
                    {
                        for (i = mColumn1 + 1; i < mColumn2; i++)
                        {
                            key = BuildKey(mRow1, i);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null)
                            {
                                mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                            }
                            xCell.Merge = SheetMergeTypes.Left | SheetMergeTypes.Right;
                        }
                        key = BuildKey(mRow1, mColumn1);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Right;
                        key = BuildKey(mRow1, mColumn2);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Left;
                    }
                    if ((mColumn2 > mColumn1) && (mRow2 > mRow1))
                    {
                        for (i = mRow1 + 1; i < mRow2; i++)
                        {
                            for (j = mColumn1 + 1; j < mColumn2; j++)
                            {
                                key = BuildKey(i, j);
                                xCell = (SheetCell)mDCells[key];
                                if (xCell == null)
                                {
                                    mDCells.Add(key, new SheetCell());
                                    xCell = (SheetCell)mDCells[key];
                                }
                                xCell.Merge = SheetMergeTypes.Top | SheetMergeTypes.Bottom | SheetMergeTypes.Left | SheetMergeTypes.Right;
                            }
                        }
                        for (i = mColumn1 + 1; i < mColumn2; i++)
                        {
                            key = BuildKey(mRow1, i);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null)
                            {
                                mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                            }
                            xCell.Merge = SheetMergeTypes.Bottom | SheetMergeTypes.Left | SheetMergeTypes.Right;
                            key = BuildKey(mRow2, i);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null)
                            {
                                mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                            }
                            xCell.Merge = SheetMergeTypes.Top | SheetMergeTypes.Left | SheetMergeTypes.Right;
                        }
                        for (i = mRow1 + 1; i < mRow2; i++)
                        {
                            key = BuildKey(i, mColumn1);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null)
                            {
                                mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                            }
                            xCell.Merge = SheetMergeTypes.Right | SheetMergeTypes.Bottom | SheetMergeTypes.Top;
                            key = BuildKey(i, mColumn2);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell == null)
                            {
                                mDCells.Add(key, new SheetCell());
                                xCell = (SheetCell)mDCells[key];
                            }
                            xCell.Merge = SheetMergeTypes.Left | SheetMergeTypes.Bottom | SheetMergeTypes.Top;
                        }
                        key = BuildKey(mRow1, mColumn1);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Right | SheetMergeTypes.Bottom;
                        key = BuildKey(mRow1, mColumn2);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Left | SheetMergeTypes.Bottom;
                        key = BuildKey(mRow2, mColumn1);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Right | SheetMergeTypes.Top;
                        key = BuildKey(mRow2, mColumn2);
                        xCell = (SheetCell)mDCells[key];
                        if (xCell == null)
                        {
                            mDCells.Add(key, new SheetCell());
                            xCell = (SheetCell)mDCells[key];
                        }
                        xCell.Merge = SheetMergeTypes.Left | SheetMergeTypes.Top;
                    }
                }
                else
                {
                    for (i = mRow1; i <= mRow2; i++)
                    {
                        for (j = mColumn1; j <= mColumn2; j++)
                        {
                            key = BuildKey(i, j);
                            xCell = (SheetCell)mDCells[key];
                            if (xCell != null) xCell.Merge = SheetMergeTypes.None;
                        }
                    }
                }
            }
        }
    }
}
